﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class frmMain : Form
    {
        public frmMain()
        {
            InitializeComponent();
        }

        
        
        
        private void btnGenerate_Click(object sender, EventArgs e)
        {
            if (chkUseSoapLogger.Checked == true)
            {

                //log soap message

                Microsoft.Crm.Sdk.Samples.SOAPLogger.Main(null);

                //load file

                //parse for request envelopes

                
            }
            //generate jscript
            GenerateCode();
        }


        /// <summary>
        /// output soap call
        /// </summary>
        private void GenerateCode()
        {
            if (txtNameSpace.Text.Length > 1 && txtFunctionName.Text.Length > 1)
            {
                string strFunctionName = txtFunctionName.Text;
                string strNameSpace = txtNameSpace.Text;

                string strInputEnvelope = txtCode.Text;
                string[] strInputLines = strInputEnvelope.Split(new Char[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries);
                StringBuilder strOutput = new StringBuilder();

                string strServiceName = "";
                if (cboService.Text.ToLower().Contains("organization"))
                {
                    strServiceName = "Organization";
                }
                else
                {
                    strServiceName = "Discovery";
                }

                //*******HEADER INFO
                StringBuilder sbHeader = new StringBuilder();
                sbHeader.Append("if (typeof (SDK) == \"undefined\")" + "\r\n");
                sbHeader.Append("   { SDK = { __namespace: true }; }" + "\r\n");
                sbHeader.Append("       //This will establish a more unique namespace for functions in this library. This will reduce the " + "\r\n");
                sbHeader.Append("       // potential for functions to be overwritten due to a duplicate name when the library is loaded." + "\r\n");
                sbHeader.Append("       SDK." + strNameSpace + " = {" + "\r\n");
                sbHeader.Append("           _getServerUrl: function () {" + "\r\n");
                sbHeader.Append("               ///<summary>" + "\r\n");
                sbHeader.Append("               /// Returns the URL for the SOAP endpoint using the context information available in the form" + "\r\n");
                sbHeader.Append("               /// or HTML Web resource." + "\r\n");
                sbHeader.Append("               ///</summary>" + "\r\n");
                sbHeader.Append("               var ServicePath = \"/XRMServices/2011/" + strServiceName + ".svc/web\";" + "\r\n");
                sbHeader.Append("               var serverUrl = \"\";" + "\r\n");
                sbHeader.Append("               if (typeof GetGlobalContext == \"function\") {" + "\r\n");
                sbHeader.Append("                   var context = GetGlobalContext();" + "\r\n");
                sbHeader.Append("                   serverUrl = context.getServerUrl();" + "\r\n");
                sbHeader.Append("               }" + "\r\n");
                sbHeader.Append("               else {" + "\r\n");
                sbHeader.Append("                   if (typeof Xrm.Page.context == \"object\") {" + "\r\n");
                sbHeader.Append("                         serverUrl = Xrm.Page.context.getServerUrl();" + "\r\n");
                sbHeader.Append("                   }" + "\r\n");
                sbHeader.Append("                   else" + "\r\n");
                sbHeader.Append("                   { throw new Error(\"Unable to access the server URL\"); }" + "\r\n");
                sbHeader.Append("                   }" + "\r\n");
                sbHeader.Append(@"                  if (serverUrl.match(/\/$/)) {");
                sbHeader.Append("\r\n");
                sbHeader.Append("                       serverUrl = serverUrl.substring(0, serverUrl.length - 1);" + "\r\n");
                sbHeader.Append("                   } " + "\r\n");
                sbHeader.Append("                   return serverUrl + ServicePath;" + "\r\n");
                sbHeader.Append("               }, " + "\r\n");
                sbHeader.Append("           " + strFunctionName + "Request: function () {" + "\r\n");
                sbHeader.Append("               var requestMain = \"\"\r\n");
                strOutput.Append(sbHeader.ToString());

                //*****REQUEST

                foreach (string line in strInputLines)
                {
                    string outline = line;
                    outline = line.Replace("\"", "\\\"");
                    strOutput.Append("               requestMain += \"" + outline + "\";" + "\r\n");
                }

                //*******FOOTER INFO

                
                StringBuilder sbFooter = new StringBuilder();
                if (chkSynchronous.Checked == false)
                {
                    sbFooter.Append("");
                    sbFooter.Append("               var req = new XMLHttpRequest();" + "\r\n");
                    sbFooter.Append("               req.open(\"POST\", SDK." + strNameSpace + "._getServerUrl(), true)" + "\r\n");
                    sbFooter.Append("               req.setRequestHeader(\"Accept\", \"application/xml, text/xml, */*\");" + "\r\n");
                    sbFooter.Append("               req.setRequestHeader(\"Content-Type\", \"text/xml; charset=utf-8\");" + "\r\n");
                    sbFooter.Append("               req.setRequestHeader(\"SOAPAction\", \"http://schemas.microsoft.com/xrm/2011/Contracts/Services/IOrganizationService/Execute\");" + "\r\n");
                    sbFooter.Append("               var successCallback = null;" + "\r\n");
                    sbFooter.Append("               var errorCallback = null;" + "\r\n");
                    sbFooter.Append("               req.onreadystatechange = function () { SDK." + strNameSpace + "." + strFunctionName + "Response(req, successCallback, errorCallback); };" + "\r\n");
                    sbFooter.Append("               req.send(requestMain);" + "\r\n");

                    sbFooter.Append("           }," + "\r\n");
                    sbFooter.Append("       " + strFunctionName + "Response: function (req, successCallback, errorCallback) {" + "\r\n");
                    sbFooter.Append("               ///<summary>" + "\r\n");
                    sbFooter.Append("               /// Recieves the assign response" + "\r\n");
                    sbFooter.Append("               ///</summary>" + "\r\n");
                    sbFooter.Append("               ///<param name=\"req\" Type=\"XMLHttpRequest\">" + "\r\n");
                    sbFooter.Append("               /// The XMLHttpRequest response" + "\r\n");
                    sbFooter.Append("               ///</param>" + "\r\n");
                    sbFooter.Append("               ///<param name=\"successCallback\" Type=\"Function\">" + "\r\n");
                    sbFooter.Append("               /// The function to perform when an successfult response is returned." + "\r\n");
                    sbFooter.Append("               /// For this message no data is returned so a success callback is not really necessary." + "\r\n");
                    sbFooter.Append("               ///</param>" + "\r\n");
                    sbFooter.Append("               ///<param name=\"errorCallback\" Type=\"Function\">" + "\r\n");
                    sbFooter.Append("               /// The function to perform when an error is returned." + "\r\n");
                    sbFooter.Append("               /// This function accepts a JScript error returned by the _getError function" + "\r\n");
                    sbFooter.Append("               ///</param>" + "\r\n");
                    sbFooter.Append("               if (req.readyState == 4) {" + "\r\n");
                    sbFooter.Append("               if (req.status == 200) {" + "\r\n");
                    sbFooter.Append("               if (successCallback != null)" + "\r\n");
                    sbFooter.Append("               { successCallback(); }" + "\r\n");
                    sbFooter.Append("               }" + "\r\n");
                    sbFooter.Append("               else {" + "\r\n");
                    sbFooter.Append("                   errorCallback(SDK." + strNameSpace + "._getError(req.responseXML));" + "\r\n");
                    sbFooter.Append("               }" + "\r\n");
                    sbFooter.Append("           }" + "\r\n");
                    sbFooter.Append("       }," + "\r\n");
                    sbFooter.Append("       _getError: function (faultXml) {" + "\r\n");
                    sbFooter.Append("           ///<summary>" + "\r\n");
                    sbFooter.Append("           /// Parses the WCF fault returned in the event of an error." + "\r\n");
                    sbFooter.Append("           ///</summary>" + "\r\n");
                    sbFooter.Append("           ///<param name=\"faultXml\" Type=\"XML\">" + "\r\n");
                    sbFooter.Append("           /// The responseXML property of the XMLHttpRequest response." + "\r\n");
                    sbFooter.Append("           ///</param>" + "\r\n");
                    sbFooter.Append("           var errorMessage = \"Unknown Error (Unable to parse the fault)\";" + "\r\n");
                    sbFooter.Append("           if (typeof faultXml == \"object\") {" + "\r\n");
                    sbFooter.Append("               try {" + "\r\n");
                    sbFooter.Append("                   var bodyNode = faultXml.firstChild.firstChild;" + "\r\n");
                    sbFooter.Append("                   //Retrieve the fault node" + "\r\n");
                    sbFooter.Append("                   for (var i = 0; i < bodyNode.childNodes.length; i++) {" + "\r\n");
                    sbFooter.Append("                       var node = bodyNode.childNodes[i];" + "\r\n");

                    sbFooter.Append("                       //NOTE: This comparison does not handle the case where the XML namespace changes" + "\r\n");
                    sbFooter.Append("                       if (\"s:Fault\" == node.nodeName) {" + "\r\n");
                    sbFooter.Append("                       for (var j = 0; j < node.childNodes.length; j++) {" + "\r\n");
                    sbFooter.Append("                           var faultStringNode = node.childNodes[j];" + "\r\n");
                    sbFooter.Append("                           if (\"faultstring\" == faultStringNode.nodeName) {" + "\r\n");
                    sbFooter.Append("                               errorMessage = faultStringNode.text;" + "\r\n");
                    sbFooter.Append("                               break;" + "\r\n");
                    sbFooter.Append("                           }" + "\r\n");
                    sbFooter.Append("                       }" + "\r\n");
                    sbFooter.Append("                       break;" + "\r\n");
                    sbFooter.Append("                   }" + "\r\n");
                    sbFooter.Append("               }" + "\r\n");
                    sbFooter.Append("           }" + "\r\n");
                    sbFooter.Append("           catch (e) { };" + "\r\n");
                    sbFooter.Append("        }" + "\r\n");
                    sbFooter.Append("        return new Error(errorMessage);" + "\r\n");
                    sbFooter.Append("     }," + "\r\n");
                    sbFooter.Append(" __namespace: true" + "\r\n");
                    sbFooter.Append("};" + "\r\n");
                }
                else
                {
                    sbFooter.Append("");
                    sbFooter.Append("               var req = new XMLHttpRequest();" + "\r\n");
                    sbFooter.Append("               req.open(\"POST\", SDK." + strNameSpace + "._getServerUrl(), false)" + "\r\n"); //false value here makes call synchronous
                    sbFooter.Append("               req.setRequestHeader(\"Accept\", \"application/xml, text/xml, */*\");" + "\r\n");
                    sbFooter.Append("               req.setRequestHeader(\"Content-Type\", \"text/xml; charset=utf-8\");" + "\r\n");
                    sbFooter.Append("               req.setRequestHeader(\"SOAPAction\", \"http://schemas.microsoft.com/xrm/2011/Contracts/Services/IOrganizationService/Execute\");" + "\r\n");
                    sbFooter.Append("               req.send(requestMain);" + "\r\n");
                    sbFooter.Append("               //work with the response here" + "\r\n");
                    sbFooter.Append("               //var strResponse = req.responseXML.xml;" + "\r\n");
                    sbFooter.Append("               //alert(strResponse.toString());" + "\r\n");

                    
                    
                    sbFooter.Append("           }," + "\r\n");
                    sbFooter.Append(" __namespace: true" + "\r\n");
                    sbFooter.Append("};" + "\r\n");
                }
                strOutput.Append(sbFooter.ToString());

                //output envelope
                txtCode.Text = strOutput.ToString();
            }
            else
            {
                MessageBox.Show("Please Fill Out All Fields!");
            }
        }

        private void label1_Click(object sender, EventArgs e)
        {
            

        }

        private void txtCode_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.KeyData == (Keys.Control | Keys.V)) (sender as TextBox).Paste(); 
        }

        private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            About frmAbout = new About();
            frmAbout.ShowDialog();
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void frmMain_Load(object sender, EventArgs e)
        {
            
        }

        private void chkUseSoapLogger_CheckedChanged(object sender, EventArgs e)
        {
            if (chkUseSoapLogger.Checked == true)
            {
                txtCrmServer.Enabled = true;
                txtDomainUser.Enabled = true;
                txtPassword.Enabled = true;

            }
            else
            {
                txtCrmServer.Enabled = false;
                txtDomainUser.Enabled = false;
                txtPassword.Enabled = false;
            }

        }

       

       

       
    }
}
